package com.chendx.store.goods.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chendx.model.common.dtos.PageResponseResult;
import com.chendx.model.common.dtos.ResponseResult;
import com.chendx.model.common.enums.AppHttpCodeEnum;
import com.chendx.model.goods.dto.CategoryDto;
import com.chendx.model.goods.pojo.Brand;
import com.chendx.model.goods.pojo.Category;
import com.chendx.model.goods.pojo.CategoryBrand;
import com.chendx.model.goods.vo.CategoryVo;
import com.chendx.store.goods.mapper.BrandMapper;
import com.chendx.store.goods.mapper.CategoryBrandMapper;
import com.chendx.store.goods.mapper.CategoryMapper;
import com.chendx.store.goods.mapper.CategoryTemplateMapper;
import com.chendx.store.goods.service.CategoryService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * Created by chendx on 2022/4/15.
 */
@Service
public class CategoryServiceImpl extends ServiceImpl<CategoryMapper,Category> implements CategoryService {
    
    @Autowired
    private CategoryBrandMapper categoryBrandMapper;
    @Autowired
    private BrandMapper brandMapper;
    @Autowired
    private CategoryTemplateMapper categoryTemplateMapper;
    @Override
    public ResponseResult findPage(CategoryDto dto) {
        //1.检查参数
        if (dto == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        //分页参数检查
        dto.checkParam();
        LambdaQueryWrapper<Category> queryWrapper = new LambdaQueryWrapper<>();
        if (!StringUtils.isEmpty(dto.getName()) && dto.getName() != null){
            queryWrapper.like(Category::getName,dto.getName());
        }
        if (!StringUtils.isEmpty(dto.getIsMenus()) && dto.getIsMenus() != null){
            queryWrapper.eq(Category::getIsMenu,dto.getIsMenus());
        }
        if (!StringUtils.isEmpty(dto.getIsShow())){
            queryWrapper.eq(Category::getIsShow,dto.getIsShow());
        }
        if (!StringUtils.isEmpty(String.valueOf(dto.getParentId())) && dto.getParentId() != null){
            queryWrapper.eq(Category::getParentId,dto.getParentId());
        }
        if (!StringUtils.isEmpty(String.valueOf(dto.getTemplateId())) && dto.getTemplateId() != null){
            queryWrapper.eq(Category::getTemplateId,dto.getTemplateId());
        }
        if (!StringUtils.isEmpty(String.valueOf(dto.getLevel())) && dto.getLevel() != null){
            queryWrapper.eq(Category::getLevel,dto.getLevel());
        }
        Page ipage = new Page<>(dto.getPage(), dto.getSize());
        IPage<Category> result = page(ipage, queryWrapper);
        PageResponseResult responseResult = new PageResponseResult(dto.getPage(),dto.getSize(), (int) result.getTotal());
        responseResult.setData(result.getRecords());
        return responseResult;
    }

    @Override
    public ResponseResult findByParentId(Integer pid) {
        if (StringUtils.isEmpty(String.valueOf(pid))){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        List<Category> list = list(Wrappers.<Category>lambdaQuery().eq(Category::getParentId, pid));
        return ResponseResult.okResult(list);
    }

    @Override
    public ResponseResult categoryTree() {
        List<Category> categoryList = list();
        List<Map<String, Object>> categoryTree = findBypid(categoryList, "0");
        return ResponseResult.okResult(categoryTree);
    }

    @Override
    public ResponseResult add(CategoryDto dto) {
        if (dto == null || dto.getName() == null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        Category category = new Category();
        category.setName(dto.getName());
        category.setParentId(dto.getParentId());
        category.setLevel(dto.getLevel());
        category.setIsShow(String.valueOf(1));
        category.setTemplateId(dto.getTemplateId());
        category.setIsMenu(String.valueOf(0));
        boolean save = save(category);
        return save?ResponseResult.okResult(AppHttpCodeEnum.SUCCESS):ResponseResult.errorResult(AppHttpCodeEnum.SERVER_ERROR);
    }

    @Override
    public ResponseResult infos(CategoryDto dto) {
        LambdaQueryWrapper<Category> queryWrapper = new LambdaQueryWrapper<>();
        if (!StringUtils.isEmpty(dto.getName()) && dto.getName() != null){
            queryWrapper.like(Category::getName,dto.getName());
        }
        if (!StringUtils.isEmpty(dto.getIsMenus()) && dto.getIsMenus() != null){
            queryWrapper.eq(Category::getIsMenu,dto.getIsMenus());
        }
        if (!StringUtils.isEmpty(dto.getIsShow())){
            queryWrapper.eq(Category::getIsShow,dto.getIsShow());
        }
        if (!StringUtils.isEmpty(String.valueOf(dto.getParentId())) && dto.getParentId() != null){
            queryWrapper.eq(Category::getParentId,dto.getParentId());
        }
        if (!StringUtils.isEmpty(String.valueOf(dto.getTemplateId())) && dto.getTemplateId() != null){
            queryWrapper.eq(Category::getTemplateId,dto.getTemplateId());
        }
        if (!StringUtils.isEmpty(String.valueOf(dto.getLevel())) && dto.getLevel() != null){
            queryWrapper.eq(Category::getLevel,dto.getLevel());
        }
        List<Category> categoryList = list(queryWrapper);
        List<CategoryVo> voList = new ArrayList<>();
        for (Category category : categoryList){
            CategoryVo categoryVo = new CategoryVo();
            BeanUtils.copyProperties(category,categoryVo);
            if (category.getLevel() == 3){
                List<CategoryBrand> categoryBrands
                        = categoryBrandMapper.selectList(Wrappers.<CategoryBrand>lambdaQuery().eq(CategoryBrand::getCategoryId, category.getId()));
                List<Integer> brandIds = categoryBrands.stream().map(x -> x.getBrandId()).collect(Collectors.toList());
                if (brandIds.size() > 0){
                    List<Brand> brandList = brandMapper.selectList(Wrappers.<Brand>lambdaQuery().in( Brand::getId, brandIds));
                    categoryVo.setBrands(brandList);
                }
            }
            voList.add(categoryVo);
        }
        return ResponseResult.okResult(voList);
    }

    @Override
    public ResponseResult findNoTemplateList() {
        List<Category> list = list(Wrappers.<Category>lambdaQuery().isNull(Category::getTemplateId).eq(Category::getLevel,3));
        return ResponseResult.okResult(list);
    }

    @Override
    public ResponseResult oneInfo(Integer id) {
        Category category = getById(id);
        CategoryVo categoryVo = new CategoryVo();
        BeanUtils.copyProperties(category,categoryVo);
        if (category.getLevel() == 3){
            List<CategoryBrand> categoryBrands
                    = categoryBrandMapper.selectList(Wrappers.<CategoryBrand>lambdaQuery().eq(CategoryBrand::getCategoryId, category.getId()));
            List<Integer> brandIds = categoryBrands.stream().map(x -> x.getBrandId()).collect(Collectors.toList());
            if (brandIds.size() > 0){
                List<Brand> brandList = brandMapper.selectList(Wrappers.<Brand>lambdaQuery().in( Brand::getId, brandIds));
                categoryVo.setBrands(brandList);
            }
        }
        return ResponseResult.okResult(categoryVo);
    }

    @Override
    public ResponseResult update(CategoryDto dto) {
        if (dto == null || dto.getName() == null || dto.getId() == null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
         }
        Category category = getById(dto.getId());
        category.setTemplateId(dto.getTemplateId());
        category.setName(dto.getName());

        List<Integer> brandIds = dto.getBrandIds();
        categoryBrandMapper.delete(Wrappers.<CategoryBrand>lambdaQuery().eq(CategoryBrand::getCategoryId, dto.getId()));
        for (Integer brandId : brandIds){
            CategoryBrand categoryBrand = new CategoryBrand();
            categoryBrand.setBrandId(brandId);
            categoryBrand.setCategoryId(dto.getId());
            categoryBrandMapper.insert(categoryBrand);
        }
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    public List<Map<String,Object>> findBypid(List<Category> categoryList,String parentId){
        if (categoryList == null) {
            return null;
        }
        List<Map<String,Object>> listMap = new ArrayList<>();
        Map<String,Object> map = null;
        for (Category category : categoryList){
            map = new HashMap<>();
            if (String.valueOf(category.getParentId()).equals(parentId)){
                map.put("name",category.getName());
                map.put("pic",category.getPic());
                map.put("id",category.getId());
                List<Map<String, Object>> maps = findBypid(categoryList, String.valueOf(category.getId()));
                if (maps.size()>0){
                    map.put("menus",findBypid(categoryList, String.valueOf(category.getId())));
                }
                listMap.add(map);
            }
        }
        return listMap;
    }
}
